//Copyright 2011 - Jonathan Allen

using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics.Contracts;

namespace Granite.ComponentModel
{
    /// <summary>
    /// Used to notify when a dictionary has been changed.
    /// </summary>
    [Pure]
    public class DictionaryChangedEventArgs : EventArgs
    {
        readonly NotifyDictionaryChangedAction m_Action;
        readonly object m_Key;
        readonly object m_NewValue;
        readonly object m_OldValue;

        /// <summary>
        /// Used when resetting the dictionary
        /// </summary>
        /// <param name="action">Must be Reset</param>
        [Pure]
        public DictionaryChangedEventArgs(NotifyDictionaryChangedAction action)
        {
            m_Action = action;
            switch (m_Action)
            {
                case NotifyDictionaryChangedAction.Reset:
                    break;
                default:
                    throw ExceptionUtilities.ArgumentOutOfRangeException("action", action, "Expected Reset");
            }

        }

        /// <summary>
        /// Used when adding or removing items
        /// </summary>
        /// <param name="action"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        [Pure]
        public DictionaryChangedEventArgs(NotifyDictionaryChangedAction action, object key, object value)
        {
            m_Action = action;
            m_Key = key;
            switch (m_Action)
            {
                case NotifyDictionaryChangedAction.Add:
                    m_NewValue = value;
                    break;
                case NotifyDictionaryChangedAction.Remove:
                    m_OldValue = value;
                    break;
                default:
                    throw ExceptionUtilities.ArgumentOutOfRangeException("action", action, "Expected Add or Remove");
            }
        }

        /// <summary>
        /// Used when replacing an item
        /// </summary>
        /// <param name="action"></param>
        /// <param name="key"></param>
        /// <param name="oldValue"></param>
        /// <param name="newValue"></param>
        [Pure]
        public DictionaryChangedEventArgs(NotifyDictionaryChangedAction action, object key, object oldValue, object newValue)
        {
            m_Action = action;
            m_Key = key;
            switch (m_Action)
            {
                case NotifyDictionaryChangedAction.Replace:
                    m_NewValue = newValue;
                    m_OldValue = oldValue;
                    break;
                default:
                    throw ExceptionUtilities.ArgumentOutOfRangeException("action", action, "Expected Replace");
            }


        }

        /// <summary>
        /// The action that was performed.
        /// </summary>
        public NotifyDictionaryChangedAction Action
        {
            get
            {
                return m_Action;
            }
        }

        /// <summary>
        /// The newly added item.
        /// </summary>
        public object NewValue
        {
            get { return m_NewValue; }
        }

        /// <summary>
        /// The removed or replaced item.
        /// </summary>
        public object OldValue
        {
            get { return m_OldValue; }
        }

        /// <summary>
        /// The key for the added or removed item
        /// </summary>
        public object Key
        {
            get { return m_Key; }
        }
    }



}
